package ia.robot.gui;

import ia.robot.app.Robot;
import ia.robot.graphics.Textures;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.border.EmptyBorder;

public class MainControlPane extends JPanel implements ActionListener {

	private static final long serialVersionUID = 1L;

	public static final String grassString = "Grass";
	public static final String stoneString = "Stone";
	public static final String botString = "Bot";
	public static final String goalString = "Goal";
	public static final String randomizeString = "Randomize";
	public static final String runString = "Run";
	public static final String testString = "Test";

	private JButton grassButton;
	private JButton stoneButton;
	private JButton botButton;
	private JButton goalButton;
	private JButton randomizeButton;
	private JButton runButton;
	private JButton testButton;
	
	private JCheckBox debugCB;
	
	private JComboBox searchMethodCB;
	private JComboBox heuristicCB;
	
	private JSlider delaySlider;

	/**
	 * 
	 */
	public MainControlPane() {

		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.setBorder(new EmptyBorder(5, 0, 0, 5));

		JLabel tileLabel = new JLabel("Tiles");
		tileLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JLabel entityLabel = new JLabel("Entities");
		entityLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JLabel delayLabel = new JLabel("Delay (in miliseconds)");
		delayLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JLabel searchMethodLabel = new JLabel ("Search method");
		searchMethodLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JLabel heuristicLabel = new JLabel ("Heuristic method");
		heuristicLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

		grassButton = new JButton(Textures.getIcon(Textures.TILE_GRASS));
		grassButton.setActionCommand(grassString);
		grassButton.setEnabled(false);
		grassButton.setFocusable (false);
		grassButton.addActionListener(this);

		stoneButton = new JButton(Textures.getIcon(Textures.TILE_STONE));
		stoneButton.setActionCommand(stoneString);
		stoneButton.setEnabled(true);
		stoneButton.setFocusable (false);
		stoneButton.addActionListener(this);

		botButton = new JButton(Textures.getIcon(Textures.TILE_BOT_SOUTH));
		botButton.setActionCommand(botString);
		botButton.setEnabled(true);
		botButton.setFocusable (false);
		botButton.addActionListener(this);

		goalButton = new JButton(Textures.getIcon(Textures.TILE_GOAL));
		goalButton.setActionCommand(goalString);
		goalButton.setEnabled(true);
		goalButton.setFocusable (false);
		goalButton.addActionListener(this);
		
		delaySlider = new JSlider(0, 1000, 500);
		delaySlider.setMajorTickSpacing (200);
		delaySlider.setMinorTickSpacing (100);
		delaySlider.setPaintTicks (true);
		delaySlider.setPaintLabels (true);
		delaySlider.setSnapToTicks (true);
		
		searchMethodCB = new JComboBox(Robot.searchMethodStrings);
		searchMethodCB.setMaximumSize(searchMethodCB.getMinimumSize());
		searchMethodCB.setPreferredSize(searchMethodCB.getMinimumSize());
		searchMethodCB.setSize(searchMethodCB.getMinimumSize());
		searchMethodCB.setFocusable(false);
		searchMethodCB.addActionListener(this);
		
		heuristicCB = new JComboBox(Robot.heuristicStrings);
		heuristicCB.setMaximumSize(heuristicCB.getMinimumSize());
		heuristicCB.setPreferredSize(heuristicCB.getMinimumSize());
		heuristicCB.setSize(heuristicCB.getMinimumSize());
		heuristicCB.setEnabled(false);
		heuristicCB.setFocusable(false);
		
		
		randomizeButton = new JButton(randomizeString);
		randomizeButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		randomizeButton.setFocusable(false);
		
		runButton = new JButton(runString);
		runButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		randomizeButton.setFocusable(false);
		
		testButton = new JButton(testString);
		testButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		randomizeButton.setFocusable(false);
		
		debugCB = new JCheckBox("Debug");
		debugCB.setAlignmentX(Component.CENTER_ALIGNMENT);
		debugCB.setFocusable(false);
		
		JPanel auxiliarLowerPane = new JPanel (new GridLayout (0, 3, 5, 5));
		auxiliarLowerPane.add(debugCB);
		auxiliarLowerPane.add(runButton);
		auxiliarLowerPane.add(testButton);
		
		JPanel lowerPane = new JPanel (new GridLayout(0, 1, 5, 5));
		lowerPane.add(randomizeButton);
		lowerPane.add(auxiliarLowerPane);
		

		this.add(Box.createVerticalGlue());
		this.add(tileLabel);
		this.add(Box.createVerticalStrut(5));
		this.add(createRowPane(grassButton, stoneButton, goalButton));
		this.add(Box.createVerticalStrut(10));
		this.add(entityLabel);
		this.add(Box.createVerticalStrut(5));
		this.add(createRowPane(botButton));
		this.add(Box.createVerticalGlue());
		this.add(new JSeparator());
		this.add(delayLabel);
		this.add(Box.createVerticalStrut(5));
		this.add(delaySlider);
		this.add(Box.createVerticalGlue());
		this.add(new JSeparator());
		this.add(searchMethodLabel);
		this.add(Box.createVerticalStrut(5));
		this.add(searchMethodCB);
		this.add(Box.createVerticalStrut(10));
		this.add(heuristicLabel);
		this.add(Box.createVerticalStrut(5));
		this.add(heuristicCB);
		this.add(Box.createVerticalGlue());
		this.add(new JSeparator());
		this.add(lowerPane);
		this.add(Box.createVerticalGlue());
	}

	/**
	 * 
	 * @param l
	 */
	public void addButtonListener(ActionListener l) {
		randomizeButton.addActionListener(l);
		runButton.addActionListener(l);
		testButton.addActionListener(l);
	}

	/**
	 * 
	 */
	public void actionPerformed(ActionEvent e) {
		String actionCommand = e.getActionCommand();

		// Si el evento fue lanzado por un boton
		if (e.getSource() instanceof JButton) {
			// Si el evento fue lanzado por el boton Grass
			if (actionCommand.equals(grassString)) {
				grassButton.setEnabled(false);
				stoneButton.setEnabled(true);
				botButton.setEnabled(true);
				goalButton.setEnabled(true);
			}

			// Si el evento fue lanzado por el boton Stone
			else if (actionCommand.equals(stoneString)) {
				grassButton.setEnabled(true);
				stoneButton.setEnabled(false);
				botButton.setEnabled(true);
				goalButton.setEnabled(true);
			}

			// Si el evento fue lanzado por el boton Bot
			else if (actionCommand.equals(botString)) {
				grassButton.setEnabled(true);
				stoneButton.setEnabled(true);
				botButton.setEnabled(false);
				goalButton.setEnabled(true);
			}

			// Si el evento fue lanzado por el boton Goal
			else if (actionCommand.equals(goalString)) {
				grassButton.setEnabled(true);
				stoneButton.setEnabled(true);
				botButton.setEnabled(true);
				goalButton.setEnabled(false);
			}
		} else if (e.getSource() instanceof JComboBox) {
			if (searchMethodCB.getSelectedIndex() == 1)
				heuristicCB.setEnabled(true);
			else
				heuristicCB.setEnabled(false);
		}
	}
	
	/**
	 * 
	 * 
	 * @param buttons
	 * @return
	 */
	private JPanel createRowPane (JButton... buttons) {
		JPanel rowPane = new JPanel ();
		rowPane.setLayout (new BoxLayout(rowPane, BoxLayout.X_AXIS));
		
		boolean first = true;
		
		for (JButton b : buttons) {
			if (!first)
				rowPane.add(Box.createRigidArea(new Dimension(5, 0)));
			
			if (first)
				first = false;
			
			rowPane.add(b);
		}
		
		rowPane.add(Box.createHorizontalGlue());
		
		return rowPane;
	}
	
	/**
	 * 
	 * @return
	 */
	public int getButtonPressed() {
		if (!grassButton.isEnabled())
			return Textures.TILE_GRASS;
		else if (!stoneButton.isEnabled())
			return Textures.TILE_STONE;
		else if (!botButton.isEnabled ())
			return Textures.TILE_BOT_SOUTH;
		else if (!goalButton.isEnabled())
			return Textures.TILE_GOAL;
		
		return 0;
	}
	
	public boolean getDebug() {
		return debugCB.isSelected();
	}
	
	public int getDelay() {
		return delaySlider.getValue();
	}
	
	public int getHeuristic() {
		return (heuristicCB.getSelectedIndex() + 1);
	}
	
	public int getSearchMethod() {
		return (searchMethodCB.getSelectedIndex() + 1);
	}
	
	public synchronized void lockControlPane() {
		grassButton.setEnabled(false);
		stoneButton.setEnabled(false);
		botButton.setEnabled(false);
		goalButton.setEnabled(false);
		
		randomizeButton.setEnabled(false);
		runButton.setEnabled(false);
		testButton.setEnabled(false);
		debugCB.setEnabled(false);
		
		delaySlider.setEnabled(false);
		searchMethodCB.setEnabled(false);
		heuristicCB.setEnabled(false);
	}
	
	public synchronized void unlockControlPane() {
		grassButton.setEnabled(false);
		stoneButton.setEnabled(true);
		botButton.setEnabled(true);
		goalButton.setEnabled(true);
		
		randomizeButton.setEnabled(true);
		runButton.setEnabled(true);
		testButton.setEnabled(true);
		debugCB.setEnabled(true);
		
		delaySlider.setEnabled(true);
		searchMethodCB.setEnabled(true);
		
		if (searchMethodCB.getSelectedIndex() == 1)
			heuristicCB.setEnabled(true);
	}
}
